home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / UTIL / SCREEN / CURSES01 / minix / c / charget < prev    next >
Text File  |  1991-05-05  |  9KB  |  266 lines

  1. /****************************************************************/
  2. /* Getch() routines of the PCcurses package            */
  3. /*                                */
  4. /****************************************************************/
  5. /* This version of curses is based on ncurses, a curses version    */
  6. /* originally written by Pavel Curtis at Cornell University.    */
  7. /* I have made substantial changes to make it run on IBM PC's,    */
  8. /* and therefore consider myself free to make it public domain.    */
  9. /*        Bjorn Larsson (...mcvax!enea!infovax!bl)    */
  10. /****************************************************************/
  11. /* 1.0:    Release:                    870515    */
  12. /****************************************************************/
  13. /* Modified to run under the MINIX operating system by Don Cope */
  14. /* These changes are also released into the public domain.      */
  15. /*                             900906  */
  16. /****************************************************************/
  17.  
  18. #include <curses.h>
  19. #include "curspriv.h"
  20.  
  21. static    int    rawgetch();        /* get raw char via BIOS */
  22. static    int    sysgetch();        /* get char via system */
  23. static    int    validchar();        /* keypad xlate and char check */
  24.  
  25. static    int    buffer[_INBUFSIZ];    /* character buffer */
  26. static    int    pindex = 0;        /* putter index */
  27. static    int    gindex = 1;        /* getter index */
  28. static    WINDOW *w;            /* to reduce stack usage */
  29. static    int    ungind = 0;        /* wungetch() push index */
  30. static    int    ungch[NUNGETCH];    /* array of ungotten chars */
  31.  
  32. /* table for key code translation of function keys in keypad mode */
  33. /* These values are for strict IBM keyboard compatibles only */
  34.  
  35. #ifndef MINIX
  36. static    int    kptab[] =
  37.   {
  38.   0x3b,KEY_F(1),  0x3c,KEY_F(2),  0x3d,KEY_F(3),  0x3e,KEY_F(4),
  39.   0x3f,KEY_F(5),  0x40,KEY_F(6),  0x41,KEY_F(7),  0x42,KEY_F(8),
  40.   0x43,KEY_F(9),  0x44,KEY_F(10), 0x47,KEY_HOME,  0x48,KEY_UP,
  41.   0x49,KEY_PPAGE, 0x4b,KEY_LEFT,  0x4d,KEY_RIGHT, 0x4f,KEY_LL,
  42.   0x50,KEY_DOWN,  0x51,KEY_NPAGE, 0x52,KEY_IC,    0x53,KEY_DC,
  43.   0x54,KEY_F(11), 0x55,KEY_F(12), 0x56,KEY_F(13), 0x57,KEY_F(14),
  44.   0x58,KEY_F(15), 0x59,KEY_F(16), 0x5a,KEY_F(17), 0x5b,KEY_F(18),
  45.   0x5c,KEY_F(19), 0x5d,KEY_F(20), 0x5e,KEY_F(21), 0x5f,KEY_F(22),
  46.   0x60,KEY_F(23), 0x61,KEY_F(24), 0x62,KEY_F(25), 0x63,KEY_F(26),
  47.   0x64,KEY_F(27), 0x65,KEY_F(28), 0x66,KEY_F(29), 0x67,KEY_F(30),
  48.   0x73,KEY_LEFT,  0x74,KEY_RIGHT,  0x75,KEY_LL,   0x76,KEY_NPAGE,
  49.   0x77,KEY_HOME,  0x84,KEY_PPAGE,  0x100,        -1
  50.   };
  51. #endif
  52.  
  53. /****************************************************************/
  54. /* Wgetch(win) gets a character from the terminal, in normal,    */
  55. /* cbreak or raw mode, optionally echoing to window  'win'.    */
  56. /****************************************************************/
  57.  
  58. int wgetch(win)
  59.   WINDOW    *win;
  60.   {
  61.   int key;
  62.   int cbr;
  63.  
  64.   if (ungind)                    /* if ungotten char exists */
  65.     return(ungch[--ungind]);            /* remove and return it */
  66.  
  67.   if ((!_cursvar.raw) && (!_cursvar.cbreak))    /* if normal */
  68.     if (gindex < pindex)            /* and data in buffer */
  69.       return(buffer[gindex++]);
  70.  
  71.   w = win;                    /* static for speed & stack */
  72.   pindex = 0;                    /* prepare to buffer data */
  73.   gindex = 0;
  74.   while(1)                    /* loop for any buffering */
  75.     {
  76.     if (_cursvar.raw)                /* get a raw character */
  77.       key = rawgetch();
  78.     else                    /* get a system character */
  79.       {
  80.       cbr = _cursesgcb();            /* get ^BREAK status */
  81.       _cursesscb(TRUE);                /* if break return proper */
  82.       key = sysgetch();
  83.       _cursesscb(cbr);                /* restore as it was */
  84.       }
  85.     if (w->_nodelay && (key == -1))        /* if nodelay and no char */
  86.       return(-1);
  87.     if ((key == '\r') && _cursvar.autocr && !_cursvar.raw) /* translate cr */
  88.       key = '\n';
  89.  
  90.     if (_cursvar.echo && (key < 0x100))        /* check if echo */
  91.       {
  92.           waddch(w,key);
  93.           wrefresh(w);
  94.       }
  95.     if (_cursvar.raw || _cursvar.cbreak)    /* if no buffering */
  96.       return(key);
  97.     if (pindex < _INBUFSIZ-2)            /* if no overflow, */
  98.       buffer[pindex++] = key;            /* put data in buffer */
  99.     if ((key == '\n') || (key == '\r'))        /* if we got a line */
  100.       return(buffer[gindex++]);
  101.     } /* while */
  102.   } /* wgetch */
  103.  
  104. /****************************************************************/
  105. /* Flushinp() kills any pending input characters.        */
  106. /****************************************************************/
  107.  
  108. void flushinp()
  109.   {
  110.   while(_curseskeytst())            /* empty keyboard buffer */
  111.     _curseskey();
  112.   kbflush();            /* empty system's buffers */
  113.   
  114.   gindex = 1;                /* set indices to kill buffer */
  115.   pindex = 0;
  116.   ungind = 0;                /* clear ungch array */
  117.   } /* flushinp */
  118.  
  119. /****************************************************************/
  120. /* Wungetch() pushes back it's argument on the input stream. If    */
  121. /* OK, returns 1, otherwise returns 0.                */
  122. /****************************************************************/
  123.  
  124. int    wungetch(ch)
  125.   int     ch;
  126.   {
  127.   if (ungind >= NUNGETCH)        /* pushback stack full */
  128.     return(0);
  129.   ungch[ungind++] = ch;
  130.   return(1);
  131.   } /* wungetch() */
  132.  
  133. /****************************************************************/
  134. /* Mvgetch() first moves the stdscr cursor to a new location,    */
  135. /* then does a wgetch() on stdscr.                */
  136. /****************************************************************/
  137.  
  138. int    mvgetch(y,x)
  139.   int y;
  140.   int x;
  141.   {
  142.   wmove(stdscr,y,x);
  143.   wgetch(stdscr);
  144.   } /* mvgetch */
  145.  
  146. /****************************************************************/
  147. /* Mvwgetch() first moves the cursor of window 'win' to a new    */
  148. /* location, then does a wgetch() in 'win'.            */
  149. /****************************************************************/
  150.  
  151. int mvwgetch(win,y,x)
  152.   WINDOW *win;
  153.   int y;
  154.   int x;
  155.   {
  156.   wmove(win,y,x);
  157.   wgetch(win);
  158.   } /* mvwgetch */
  159.  
  160. /****************************************************************/
  161. /* rawgetch() gets a character without any interpretation at    */
  162. /* all and returns it. If keypad mode is active for the desig-    */
  163. /* nated window, function key translation will be performed.    */
  164. /* Otherwise, function keys are ignored.If nodelay mode is    */
  165. /* active in the window, then rawgetch() returns -1 if no cha-    */
  166. /* racter is available.                        */
  167. /****************************************************************/
  168.  
  169. static int rawgetch()
  170.   {
  171.   int c;
  172.  
  173.   if (w->_nodelay && !_curseskeytst())
  174.     return(-1);
  175.   while(1)                      /* loop to get valid char */
  176.     {
  177.     if ((c = validchar(_curseskey())) >= 0)
  178.           return(c);
  179.     } /* while */
  180.   } /* rawgetch */
  181.  
  182. /****************************************************************/
  183. /* Sysgetch() gets a character with normal ^S, ^Q, ^P and ^C    */
  184. /* interpretation and returns it. If keypad mode is active for    */
  185. /* the designated window, function key translation will be per-    */
  186. /* formed. Otherwise, function keys are ignored. If nodelay    */
  187. /* mode is active in the window, then sysgetch() returns -1 if    */
  188. /* no character is available.                    */
  189. /****************************************************************/
  190. #ifndef MINIX
  191. #undef getch                    /* we use MSC getch() below */
  192. #endif
  193. static int sysgetch()
  194.   {
  195. #ifndef MINIX
  196.   int c;
  197. #endif
  198.  
  199.   if (w->_nodelay && !kbhit())
  200.     return(-1);
  201. #ifdef MINIX
  202.     return(_curseskey());
  203. #else
  204.   while(1)
  205.     {
  206.     c = _curseskey();
  207.  
  208.     if (c)                    /* if not a function key */
  209.       return(c & 0xff);                /* avoids sign-extending */
  210.     c = getch();
  211.     if ((c = validchar(c << 8)) >= 0)        /* get & check next char */
  212.       return(c);
  213.     } /* while */
  214. #endif
  215.   } /* sysgetch */
  216.  
  217. /****************************************************************/
  218. /* Validchar(c) chacks that 'c' is a valid character, and    */
  219. /* if so returns it, with function key translation applied if    */
  220. /* 'w' has keypad mode set. If char is invalid, returns -1.    */
  221. /****************************************************************/
  222.  
  223. static int validchar(c)
  224.   int    c;
  225.   {
  226. #ifdef MINIX
  227.   return (c & 0xff);
  228. #else
  229.   int *scanp;
  230.  
  231.   if (c == 0x0300)            /* special case, ^@ = NULL */
  232.     return(0);
  233.   if (!(c & 0x00))            /* normal character */
  234.     return(c & 0xff);
  235.   if (!(w->_keypad))            /* skip f keys if not keypad mode */
  236.     return(-1);
  237.   c = (c >> 8) & 0xff;
  238.   scanp = kptab;
  239.   while(*scanp <= c)            /* search for value */
  240.     {                    /* (stops on table entry 0x100) */
  241.     if (*scanp++ == c)
  242.       return(*scanp);            /* found, return it */
  243.     scanp++;
  244.     }
  245.   return(-1);                /* not found, invalid */
  246.  
  247. #endif
  248.   } /* validchar */
  249.  
  250. /****************************************************************/
  251. /* _cursespendch() returns 1 if there is any character avai-    */
  252. /* lable, and 0 if there is none. this is not for programmer    */
  253. /* usage, but for the updatew routines.                */
  254. /****************************************************************/
  255.  
  256. bool    _cursespendch()
  257.   {
  258.   if (ungind)                /* ungotten char */
  259.     return(TRUE);
  260.   if (pindex > gindex)            /* buffered char */
  261.     return(TRUE);
  262.   if (_cursvar.raw)            /* raw mode test */
  263.     return(_curseskeytst());
  264.   return(kbhit());            /* normal mode test */
  265.   } /* _cursespendch */
  266.